package tgeo;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.MalformedInputException;
import java.util.Map;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.part.ViewPart;

public class FileReadView extends ViewPart {

	Button radioHex = null;
	Button radioStr = null;

	Text txtFilePath = null;
	Button btnOpenFile = null;
	Button btnReload = null;
	Button chkBlockSelection = null;
	StyledText txtFile = null;

	FileChannel in = null;
	Combo cboEncoding = null;

	final int PAD = 10;
	
	public FileReadView() {
	}


	@Override
	public void createPartControl(final Composite parent) {
		parent.setBackgroundMode(SWT.INHERIT_DEFAULT);
		Layout layout = new FormLayout();
		FormData data = null;
		parent.setLayout(layout);
		Composite composite0 = new Composite(parent, SWT.NONE);
		composite0.setLayout(parent.getLayout());

		radioHex = new Button(composite0, SWT.RADIO);
		radioStr = new Button(composite0, SWT.RADIO);
		cboEncoding = new Combo(composite0, SWT.BORDER);
		txtFilePath = new Text(parent, SWT.BORDER | SWT.READ_ONLY);
		btnOpenFile = new Button(parent, SWT.PUSH);
		btnReload = new Button(parent, SWT.PUSH);
		txtFile = new StyledText(parent, SWT.BORDER | SWT.V_SCROLL
				| SWT.H_SCROLL);
		chkBlockSelection = new Button(parent, SWT.CHECK);

		txtFile.setFont(new Font(null, "fixedsys", 10, SWT.NONE));
		radioHex.setText("Hex");
		radioStr.setText("Text");
		radioStr.setSelection(true);
		btnOpenFile.setText("Open");
		btnReload.setText("Reload");
		chkBlockSelection.setText("Block Selection");

		Map<String, Charset> mapCharset = Charset.availableCharsets();
		for (String k : mapCharset.keySet()) {
			Charset charset = mapCharset.get(k);
			cboEncoding.add(charset.toString());
		}
		cboEncoding.setText(Charset.defaultCharset().toString());

		data = new FormData();
		data.top = new FormAttachment(0, PAD);
		data.left = new FormAttachment(0, PAD);
		composite0.setLayoutData(data);

		data = new FormData();
		data.top = new FormAttachment(0, PAD);
		data.left = new FormAttachment(0, PAD);
		radioHex.setLayoutData(data);

		data = new FormData();
		data.top = new FormAttachment(radioHex, PAD);
		data.left = new FormAttachment(0, PAD);
		radioStr.setLayoutData(data);

		data = new FormData();
		data.top = new FormAttachment(radioHex, PAD);
		data.left = new FormAttachment(radioStr, PAD);
		cboEncoding.setLayoutData(data);
		
		data = new FormData();
		data.top = new FormAttachment(composite0, PAD);
		data.right = new FormAttachment(100, -PAD);
		btnReload.setLayoutData(data);

		data = new FormData();
		data.top = new FormAttachment(composite0, PAD);
		data.right = new FormAttachment(btnReload, -PAD);
		btnOpenFile.setLayoutData(data);
		
		data = new FormData();
		data.top = new FormAttachment(composite0, PAD);
		data.left = new FormAttachment(0, PAD);
		data.right = new FormAttachment(btnOpenFile, -PAD);
		txtFilePath.setLayoutData(data);

		data = new FormData();
		data.top = new FormAttachment(btnOpenFile, PAD);
		data.left = new FormAttachment(0, PAD);
		chkBlockSelection.setLayoutData(data);
		
		data = new FormData();
		data.top = new FormAttachment(chkBlockSelection, PAD);
		data.left = new FormAttachment(0, PAD);
		data.right = new FormAttachment(100, -PAD);
		data.bottom = new FormAttachment(100, -PAD);
		txtFile.setLayoutData(data);

		btnOpenFile.addSelectionListener(new SelectionListener() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				FileDialog dlg = new FileDialog(parent.getShell(), SWT.OPEN);
				// dlg.setFilterExtensions(new String []{"*.xsd"});
				String path = dlg.open();
				if (path == null)
					return;
				txtFilePath.setText(path);
				OpenFile(path);
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
			}
		});
		btnReload.addSelectionListener(new SelectionListener() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				String path = txtFilePath.getText();
				if (path == null)
					return;
				txtFilePath.setText(path);
				OpenFile(path);
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
			}
		});
		
		chkBlockSelection.addSelectionListener(new SelectionListener() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				txtFile.setBlockSelection(chkBlockSelection.getSelection());
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
			}
		});

	}

	@Override
	public void setFocus() {

	}

	void OpenFile(String path){
		try {
			FileChannel fc = new FileInputStream(path).getChannel();
			System.out.println("file size: " + fc.size());
			ByteBuffer buff = fc.map(FileChannel.MapMode.READ_ONLY, 0,
					fc.size());
			if (radioHex.getSelection()) {
				byte[] dst = new byte[(int) fc.size()];
				buff.get(dst);
				StringBuffer sb = new StringBuffer();
				StringBuffer sbAscii = new StringBuffer();
				for (int i = 0; i < ((dst.length + 15) / 16 * 16); i++) {
					try {
						char ch = ' ';
						if (i < dst.length)
							ch = (char) dst[i];
						else
							ch = ' ';
						if (i % 16 == 0) {
							sb.append(String.format("%07x: ", i));
							sbAscii.setLength(0);
						}
						if(i<dst.length)
							sb.append(String.format("%02x", dst[i]));
						else
							sb.append("  ");
						if(i<dst.length){
							if (dst[i] >= 0x20 && dst[i] <= 0x7e)
								sbAscii.append(ch);
							else
								sbAscii.append(".");
						}else{
							sbAscii.append(" ");
						}
						if (i % 2 == 1)
							sb.append(" ");
						if ((i + 1) % 16 == 0) {
							sb.append(sbAscii);
							sb.append("\n");
						}
					} catch (Exception e1) {
						e1.printStackTrace();
					}

				}
				
				txtFile.setText(sb.toString());
			} else {
				String charsetName = cboEncoding.getText();
				Charset charset = Charset.forName(charsetName);
				System.out.println(charset.toString());
				try {
					CharsetDecoder decoder = charset.newDecoder();
					CharBuffer charBuffer = decoder.decode(buff);
					txtFile.setText(charBuffer.toString());
				} catch (MalformedInputException e3) {

				}
			}
			txtFile.setSelection(txtFile.getCharCount());
			fc.close();
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		} catch (IOException e2) {
			e2.printStackTrace();
		} catch(Exception e){
			e.printStackTrace();
		}
	}
}
